home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) import socket import re import gzip import os.path as os import time import urllib import StringIO import httplib import struct from g import * from codes import * import utils import status import pml from prnt import pcl, ldl, cups import models import mdns import slp from strings import StringTable try: import hpmudext except ImportError: if not os.getenv('HPLIP_BUILD'): log.error('HPMUDEXT could not be loaded. Please check HPLIP installation.') sys.exit(1) except: not os.getenv('HPLIP_BUILD') try: MAX_BUFFER = hpmudext.HPMUD_BUFFER_SIZE except AttributeError: MAX_BUFFER = 8192 dbus_avail = False dbus_disabled = False try: import dbus from dbus import lowlevel, SessionBus dbus_avail = True except ImportError: log.warn('python-dbus not installed.') import warnings warnings.simplefilter('ignore', DeprecationWarning) DEFAULT_PROBE_BUS = [ 'usb', 'par', 'cups'] VALID_BUSES = ('par', 'net', 'cups', 'usb') VALID_BUSES_WO_CUPS = ('par', 'net', 'usb') DEFAULT_FILTER = None VALID_FILTERS = ('print', 'scan', 'fax', 'pcard', 'copy') DEFAULT_BE_FILTER = ('hp',) pat_deviceuri = re.compile('(.*):/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*)|ip=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}[^&]*)|zc=(\\S+))(?:&port=(\\d))?', re.IGNORECASE) http_pat_url = re.compile('/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*))&loc=(\\S*)', re.IGNORECASE) direct_pat = re.compile('direct (.*?) "(.*?)" "(.*?)" "(.*?)"', re.IGNORECASE) pat_dynamic_ctr = re.compile('CTR:\\d*\\s.*;', re.IGNORECASE) model_dat = models.ModelData() ip_pat = re.compile('\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b', re.IGNORECASE) dev_pat = re.compile('/dev/.+', re.IGNORECASE) usb_pat = re.compile('(\\d+):(\\d+)', re.IGNORECASE) class Event(object): def __init__(self, device_uri, printer_name, event_code, username = prop.username, job_id = 0, title = '', timedate = 0): self.device_uri = unicode(utils.xrstrip(device_uri, '\x00'))[:64].encode('utf-8') self.printer_name = unicode(utils.xrstrip(printer_name, '\x00'))[:64].encode('utf-8') self.event_code = int(event_code) self.username = unicode(utils.xrstrip(username, '\x00'))[:32].encode('utf-8') self.job_id = int(job_id) self.title = unicode(utils.xrstrip(title, '\x00'))[:64].encode('utf-8') if timedate: self.timedate = float(timedate) else: self.timedate = time.time() self.pipe_fmt = '64s64sI32sI64sf' self.dbus_fmt = 'ssisisd' def debug(self): log.debug(' device_uri=%s' % self.device_uri) log.debug(' printer_name=%s' % self.printer_name) log.debug(' event_code=%d' % self.event_code) log.debug(' username=%s' % self.username) log.debug(' job_id=%d' % self.job_id) log.debug(' title=%s' % self.title) log.debug(' timedate=%s' % self.timedate) def pack_for_pipe(self): return struct.pack(self.pipe_fmt, self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate) def send_via_pipe(self, fd, recipient = 'hpssd'): if fd is not None: log.debug('Sending event %d to %s (via pipe %d)...' % (self.event_code, recipient, fd)) try: os.write(fd, self.pack_for_pipe()) return True except OSError: log.debug('Failed.') return False None<EXCEPTION MATCH>OSError def send_via_dbus(self, session_bus, interface = 'com.hplip.StatusService'): if session_bus is not None and dbus_avail: log.debug('Sending event %d to %s (via dbus)...' % (self.event_code, interface)) msg = lowlevel.SignalMessage('/', interface, 'Event') msg.append(signature = self.dbus_fmt, *self.as_tuple()) session_bus.send_message(msg) def copy(self): return Event(*self.as_tuple()) def __str__(self): return "<Event('%s', '%s', %d, '%s', %d, '%s', %f)>" % self.as_tuple() def as_tuple(self): return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate) class FaxEvent(Event): def __init__(self, temp_file, event): Event.__init__(self, *event.as_tuple()) self.temp_file = temp_file self.pipe_fmt = '64s64sI32sI64sfs' self.dbus_fmt = 'ssisisfs' def debug(self): log.debug('FAX:') Event.debug(self) log.debug(' temp_file=%s' % self.temp_file) def __str__(self): return "<FaxEvent('%s', '%s', %d, '%s', %d, '%s', %f, '%s')>" % self.as_tuple() def as_tuple(self): return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate, self.temp_file) class DeviceIOEvent(Event): def __init__(self, bytes_written, event): Event.__init__(self, *event.as_tuple()) self.bytes_written = bytes_written self.pipe_fmt = '64s64sI32sI64sfI' self.dbus_fmt = 'ssisisfi' def debug(self): log.debug('DEVIO:') Event.debug(self) log.debug(' bytes_written=%d' % self.bytes_written) def __str__(self): return "<DeviceIOEvent('%s', '%s', %d, '%s', %d, '%s', %f, '%d')>" % self.as_tuple() def as_tuple(self): return (self.device_uri, self.printer_name, self.event_code, self.username, self.job_id, self.title, self.timedate, self.bytes_written) def init_dbus(dbus_loop = None): global dbus_avail, dbus_avail, dbus_avail, dbus_avail, dbus_avail service = None session_bus = None if not prop.gui_build: dbus_avail = False return (dbus_avail, None, None) if dbus_avail and not dbus_disabled: if os.getuid() == 0: log.debug('Not starting dbus: running as root.') dbus_avail = False return (dbus_avail, None, None) try: if dbus_loop is None: session_bus = dbus.SessionBus() else: session_bus = dbus.SessionBus(dbus_loop) except dbus.exceptions.DBusException: os.getuid() == 0 e = os.getuid() == 0 prop.gui_build if os.getuid() != 0: log.error('Unable to connect to dbus session bus.') else: log.debug('Unable to connect to dbus session bus (running as root?)') dbus_avail = False return (dbus_avail, None, None) try: log.debug('Connecting to com.hplip.StatusService (try #1)...') service = session_bus.get_object('com.hplip.StatusService', '/com/hplip/StatusService') dbus_avail = True except dbus.exceptions.DBusException: os.getuid() == 0 e = os.getuid() == 0 prop.gui_build try: os.waitpid(-1, os.WNOHANG) except OSError: pass path = utils.which('hp-systray') log.debug('Running hp-systray: %s --force-startup' % path) os.spawnlp(os.P_NOWAIT, path, 'hp-systray', '--force-startup') log.debug('Waiting for hp-systray to start...') time.sleep(1) t = 2 while True: try: log.debug('Connecting to com.hplip.StatusService (try #%d)...' % t) service = session_bus.get_object('com.hplip.StatusService', '/com/hplip/StatusService') except dbus.exceptions.DBusException: None if path else os.path.exists(path) e = None if path else os.path.exists(path) log.debug('Unable to connect to dbus. Is hp-systray running?') t += 1 if t > 5: log.warn('Unable to connect to dbus. Is hp-systray running?') return (False, None, None) time.sleep(1) continue t > 5 log.debug('Connected.') dbus_avail = True break continue None if path else os.path.exists(path) except: os.getuid() == 0<EXCEPTION MATCH>dbus.exceptions.DBusException os.getuid() == 0 return (dbus_avail, service, session_bus) def makeURI(param, port = 1): (cups_uri, sane_uri, fax_uri) = ('', '', '') found = False if dev_pat.search(param) is not None: log.debug('Trying parallel with %s' % param) (result_code, uri) = hpmudext.make_par_uri(param) if result_code == hpmudext.HPMUD_R_OK and uri: log.debug('Found: %s' % uri) found = True cups_uri = uri else: log.debug('Not found.') elif usb_pat.search(param) is not None: match_obj = usb_pat.search(param) usb_bus_id = match_obj.group(1) usb_dev_id = match_obj.group(2) log.debug('Trying USB with bus=%s dev=%s...' % (usb_bus_id, usb_dev_id)) (result_code, uri) = hpmudext.make_usb_uri(usb_bus_id, usb_dev_id) if result_code == ERROR_SUCCESS and uri: log.debug('Found: %s' % uri) found = True cups_uri = uri else: log.debug('Not found.') elif ip_pat.search(param) is not None: log.debug('Trying IP address %s' % param) (result_code, uri) = hpmudext.make_net_uri(param, port) if result_code == hpmudext.HPMUD_R_OK and uri: log.debug('Found: %s' % uri) found = True cups_uri = uri else: log.debug('Not found.') else: log.debug('Trying ZC hostname %s' % param) (result_code, uri) = hpmudext.make_zc_uri(param, port) if result_code == hpmudext.HPMUD_R_OK and uri: log.debug('Found: %s' % uri) found = True cups_uri = uri else: log.debug('Not found.') if not found: log.debug('Trying serial number %s' % param) devices = probeDevices(bus = [ 'usb', 'par']) for d in devices: log.debug(d) try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = parseDeviceURI(d) except Error: continue if bus == 'par': mq = queryModelByURI(d) (result_code, device_id) = hpmudext.device_open(d, mq.get('io-mode', hpmudext.HPMUD_UNI_MODE)) if result_code == hpmudext.HPMUD_R_OK: (result_code, data) = hpmudext.get_device_id(device_id) serial = parseDeviceID(data).get('SN', '') hpmudext.close_device(device_id) if serial.lower() == param.lower(): log.debug('Found: %s' % d) found = True cups_uri = d break continue log.debug('Not found.') if found: try: mq = queryModelByURI(cups_uri) except Error: e = None log.error('Error: %s' % e.msg) (cups_uri, sane_uri, fax_uri) = ('', '', '') if mq.get('support-type', SUPPORT_TYPE_NONE) > SUPPORT_TYPE_NONE: if mq.get('scan-type', 0): sane_uri = cups_uri.replace('hp:', 'hpaio:') if mq.get('fax-type', 0): fax_uri = cups_uri.replace('hp:', 'hpfax:') else: (cups_uri, sane_uri, fax_uri) = ('', '', '') else: (scan_uri, fax_uri) = ('', '') if cups_uri: user_conf.set('last_used', 'device_uri', cups_uri) return (cups_uri, sane_uri, fax_uri) def queryModelByModel(model): model = models.normalizeModelName(model).lower() return model_dat[model] def queryModelByURI(device_uri): try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = parseDeviceURI(device_uri) except Error: raise Error(ERROR_INVALID_DEVICE_URI) return queryModelByModel(model) def probeDevices(bus = DEFAULT_PROBE_BUS, timeout = 10, ttl = 4, filter = DEFAULT_FILTER, search = '', net_search = 'mdns', back_end_filter = ('hp',)): num_devices = 0 ret_devices = { } if search: try: search_pat = re.compile(search, re.IGNORECASE) log.error('Invalid search pattern. Search uses standard regular expressions. For more info, see: http://www.amk.ca/python/howto/regex/') search = '' for b in bus: log.debug('Probing bus: %s' % b) if b not in VALID_BUSES: log.error('Invalid bus: %s' % b) continue if b == 'net': if net_search == 'slp': try: detected_devices = slp.detectNetworkDevices(ttl, timeout) except Error: socket.error = None log.error('An error occured during network probe.') raise ERROR_INTERNAL except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error try: detected_devices = mdns.detectNetworkDevices(ttl, timeout) except Error: socket.error = None log.error('An error occured during network probe.') raise ERROR_INTERNAL for ip in detected_devices: update_spinner() hn = detected_devices[ip].get('hn', '?UNKNOWN?') num_devices_on_jd = detected_devices[ip].get('num_devices', 0) num_ports_on_jd = detected_devices[ip].get('num_ports', 1) if num_devices_on_jd > 0: for port in range(num_ports_on_jd): dev = detected_devices[ip].get('device%d' % (port + 1), '0') if dev is not None and dev != '0': device_id = parseDeviceID(dev) model = models.normalizeModelName(device_id.get('MDL', '?UNKNOWN?')) if num_ports_on_jd == 1: if net_search == 'slp': device_uri = 'hp:/net/%s?ip=%s' % (model, ip) else: device_uri = 'hp:/net/%s?zc=%s' % (model, hn) elif net_search == 'slp': device_uri = 'hp:/net/%s?ip=%s&port=%d' % (model, ip, port + 1) else: device_uri = 'hp:/net/%s?zc=%s&port=%d' % (model, hn, port + 1) include = True mq = queryModelByModel(model) if not mq: log.debug('Not found.') include = False elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE: log.debug('Not supported.') include = False elif filter not in (None, 'print', 'print-type'): include = __checkFilter(filter, mq) if include: ret_devices[device_uri] = (model, model, hn) include if b in ('usb', 'par'): if b == 'par': bn = hpmudext.HPMUD_BUS_PARALLEL else: bn = hpmudext.HPMUD_BUS_USB (result_code, data) = hpmudext.probe_devices(bn) if result_code == hpmudext.HPMUD_R_OK: for x in data.splitlines(): m = direct_pat.match(x) if not m.group(1): pass uri = '' if not m.group(2): pass mdl = '' if not m.group(3): pass desc = '' if not m.group(4): pass devid = '' log.debug(uri) try: (back_end, is_hp, bb, model, serial, dev_file, host, zc, port) = parseDeviceURI(uri) except Error: continue include = True if mdl and uri and is_hp: mq = queryModelByModel(model) if not mq: log.debug('Not found.') include = False elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE: log.debug('Not supported.') include = False elif filter not in (None, 'print', 'print-type'): include = __checkFilter(filter, mq) if include: ret_devices[uri] = (mdl, desc, devid) include result_code == hpmudext.HPMUD_R_OK if b == 'cups': cups_printers = cups.getPrinters() x = len(cups_printers) for p in cups_printers: device_uri = p.device_uri log.debug('%s: %s' % (device_uri, p.name)) if device_uri != '': try: (back_end, is_hp, bs, model, serial, dev_file, host, zc, port) = parseDeviceURI(device_uri) except Error: log.debug('Unrecognized URI: %s' % device_uri) continue if not is_hp: continue include = True mq = queryModelByModel(model) if not mq: include = False log.debug('Not found.') elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE: log.debug('Not supported.') include = False elif filter not in (None, 'print', 'print-type'): include = __checkFilter(filter, mq) if include: ret_devices[device_uri] = (model, model, '') include probed_devices = { } for uri in ret_devices: num_devices += 1 (mdl, model, devid_or_hn) = ret_devices[uri] include = True if search: match_obj = search_pat.search('%s %s %s %s' % (mdl, model, devid_or_hn, uri)) if match_obj is None: log.debug("%s %s %s %s: Does not match search '%s'." % (mdl, model, devid_or_hn, uri, search)) include = False if include: probed_devices[uri] = ret_devices[uri] continue cleanup_spinner() return probed_devices def getSupportedCUPSDevices(back_end_filter = [ 'hp'], filter = DEFAULT_FILTER): devices = { } printers = cups.getPrinters() for p in printers: try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = parseDeviceURI(p.device_uri) except Error: continue if (back_end_filter == '*' and back_end in back_end_filter or 'hpaio' in back_end_filter or back_end == 'hp') and model and is_hp: include = True mq = queryModelByModel(model) if not mq: log.debug('Not found.') include = False elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE: log.debug('Not supported.') include = False elif filter not in (None, 'print', 'print-type'): include = __checkFilter(filter, mq) if include: if 'hpaio' in back_end_filter: d = p.device_uri.replace('hp:', 'hpaio:') else: d = p.device_uri try: devices[d] except KeyError: devices[d] = [ p.name] devices[d].append(p.name) include return devices def getSupportedCUPSPrinters(back_end_filter = [ 'hp'], filter = DEFAULT_FILTER): printer_list = [] printers = cups.getPrinters() for p in printers: try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = parseDeviceURI(p.device_uri) except Error: continue if (back_end_filter == '*' or back_end in back_end_filter) and model and is_hp: include = True mq = queryModelByModel(model) if not mq: log.debug('Not found.') include = False elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE: log.debug('Not supported.') include = False elif filter not in (None, 'print', 'print-type'): include = __checkFilter(filter, mq) if include: p.name = p.name.decode('utf-8') printer_list.append(p) include return printer_list def getSupportedCUPSPrinterNames(back_end_filter = [ 'hp'], filter = DEFAULT_FILTER): printers = getSupportedCUPSPrinters(back_end_filter, filter) return [ p.name for p in printers ] def getDeviceURIByPrinterName(printer_name, scan_uri_flag = False): if printer_name is None: return None device_uri = None printers = cups.getPrinters() for p in printers: try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = parseDeviceURI(p.device_uri) except Error: printer_name is None printer_name is None continue except: printer_name is None if is_hp and p.name == printer_name: if scan_uri_flag: device_uri = p.device_uri.replace('hp:', 'hpaio:') else: device_uri = p.device_uri break continue return device_uri def parseDeviceID(device_id): d = { } x = _[1] for z in x: y = z.split(':') try: d.setdefault(y[0].strip(), y[1]) continue except IndexError: [] [] [] d.setdefault(y[0].strip(), None) continue d.setdefault('MDL', '') d.setdefault('SN', '') if 'SERIAL' in d: d['SN'] = d['SERIAL'] del d['SERIAL'] elif 'SERN' in d: d['SN'] = d['SERN'] del d['SERN'] if d['SN'].startswith('X'): d['SN'] = '' return d def parseDynamicCounter(ctr_field, convert_to_int = True): (counter, value) = ctr_field.split(' ') try: if not utils.xlstrip(str(counter), '0'): pass counter = int('0') if convert_to_int: if not utils.xlstrip(str(value), '0'): pass value = int('0') except ValueError: if convert_to_int: (counter, value) = (0, 0) else: (counter, value) = (0, '') except: convert_to_int return (counter, value) def parseDeviceURI(device_uri): m = pat_deviceuri.match(device_uri) if m is None: log.debug('Device URI %s is invalid/unknown' % device_uri) raise Error(ERROR_INVALID_DEVICE_URI) m is None if not m.group(1).lower(): pass back_end = '' is_hp = back_end in ('hp', 'hpfax', 'hpaio') if not m.group(2).lower(): pass bus = '' if bus not in ('usb', 'net', 'bt', 'fw', 'par'): log.debug('Device URI %s is invalid/unknown' % device_uri) raise Error(ERROR_INVALID_DEVICE_URI) bus not in ('usb', 'net', 'bt', 'fw', 'par') if not m.group(3): pass model = '' if not m.group(4): pass serial = '' if not m.group(5): pass dev_file = '' if not m.group(6): pass host = '' zc = '' if not host: if not m.group(7): pass zc = host = '' if not m.group(8): pass port = 1 if bus == 'net': try: port = int(port) except (ValueError, TypeError): port = 1 if port == 0: port = 1 log.debug('%s: back_end:%s is_hp:%s bus:%s model:%s serial:%s dev_file:%s host:%s zc:%s port:%s' % (device_uri, back_end, is_hp, bus, model, serial, dev_file, host, zc, port)) return (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) def isLocal(bus): return bus in ('par', 'usb', 'fw', 'bt') def isNetwork(bus): return bus in ('net',) def __checkFilter(filter, mq): for f, p in filter.items(): if f is not None: (op, val) = p if not op(mq[f], val): return False continue op(mq[f], val) return True def validateBusList(bus, allow_cups = True): for b in bus: if allow_cups: vb = VALID_BUSES else: vb = VALID_BUSES_WO_CUPS if b not in vb: log.error('Invalid bus name: %s' % b) return False return True def validateFilterList(filter): if filter is None: return True for f in filter: if f not in VALID_FILTERS: log.error("Invalid term '%s' in filter list" % f) return False return True inter_pat = re.compile('%(.*)%', re.IGNORECASE) st = StringTable() strings_init = False def initStrings(): global strings_init strings_init = True cycles = 0 while True: found = False for s in st.string_table: (short_string, long_string) = st.string_table[s] short_replace = short_string long_replace = long_string try: short_match = inter_pat.match(short_string).group(1) except (AttributeError, TypeError): short_match = None if short_match is not None: found = True try: (short_replace, dummy) = st.string_table[short_match] except KeyError: log.error('String interpolation error: %s' % short_match) except: None<EXCEPTION MATCH>KeyError None<EXCEPTION MATCH>KeyError try: long_match = inter_pat.match(long_string).group(1) except (AttributeError, TypeError): long_match = None if long_match is not None: found = True try: (dummy, long_replace) = st.string_table[long_match] except KeyError: log.error('String interpolation error: %s' % long_match) except: None<EXCEPTION MATCH>KeyError None<EXCEPTION MATCH>KeyError if found: st.string_table[s] = (short_replace, long_replace) continue if not found: break continue cycles += 1 if cycles > 1000: break continue def queryString(string_id, typ = 0): if not strings_init: initStrings() s = st.string_table.get(str(string_id), ('', ''))[typ] if type(s) == type(''): return s return s() AGENT_types = { AGENT_TYPE_NONE: 'invalid', AGENT_TYPE_BLACK: 'black', AGENT_TYPE_CMY: 'cmy', AGENT_TYPE_KCM: 'kcm', AGENT_TYPE_CYAN: 'cyan', AGENT_TYPE_MAGENTA: 'magenta', AGENT_TYPE_YELLOW: 'yellow', AGENT_TYPE_CYAN_LOW: 'photo_cyan', AGENT_TYPE_MAGENTA_LOW: 'photo_magenta', AGENT_TYPE_YELLOW_LOW: 'photo_yellow', AGENT_TYPE_GGK: 'photo_gray', AGENT_TYPE_BLUE: 'photo_blue', AGENT_TYPE_KCMY_CM: 'kcmy_cm', AGENT_TYPE_LC_LM: 'photo_cyan_and_photo_magenta', AGENT_TYPE_LG_PK: 'light_gray_and_photo_black', AGENT_TYPE_LG: 'light_gray', AGENT_TYPE_G: 'medium_gray', AGENT_TYPE_PG: 'photo_gray', AGENT_TYPE_C_M: 'cyan_and_magenta', AGENT_TYPE_K_Y: 'black_and_yellow', AGENT_TYPE_UNSPECIFIED: 'unspecified' } AGENT_kinds = { AGENT_KIND_NONE: 'invalid', AGENT_KIND_HEAD: 'head', AGENT_KIND_SUPPLY: 'supply', AGENT_KIND_HEAD_AND_SUPPLY: 'cartridge', AGENT_KIND_TONER_CARTRIDGE: 'toner', AGENT_KIND_MAINT_KIT: 'maint_kit', AGENT_KIND_ADF_KIT: 'adf_kit', AGENT_KIND_DRUM_KIT: 'drum_kit', AGENT_KIND_TRANSFER_KIT: 'transfer_kit', AGENT_KIND_INT_BATTERY: 'battery', AGENT_KIND_UNKNOWN: 'unknown' } AGENT_healths = { AGENT_HEALTH_OK: 'ok', AGENT_HEALTH_MISINSTALLED: 'misinstalled', AGENT_HEALTH_INCORRECT: 'incorrect', AGENT_HEALTH_FAILED: 'failed', AGENT_HEALTH_OVERTEMP: 'overtemp', AGENT_HEALTH_CHARGING: 'charging', AGENT_HEALTH_DISCHARGING: 'discharging' } AGENT_levels = { AGENT_LEVEL_TRIGGER_MAY_BE_LOW: 'low', AGENT_LEVEL_TRIGGER_PROBABLY_OUT: 'low', AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT: 'out' } string_cache = { } class Device(object): def __init__(self, device_uri, printer_name = None, service = None, callback = None, disable_dbus = False): global dbus_disabled log.debug('Device URI: %s' % device_uri) log.debug('Printer: %s' % printer_name) dbus_disabled = disable_dbus if not disable_dbus: if service is None: (self.dbus_avail, self.service, session_bus) = init_dbus() else: self.dbus_avail = True self.service = service else: self.dbus_avail = False self.service = None self.last_event = None printers = cups.getPrinters() if device_uri is None and printer_name is not None: for p in printers: if p.name.lower() == printer_name.lower(): device_uri = p.device_uri log.debug('Device URI: %s' % device_uri) break continue else: raise Error(ERROR_DEVICE_NOT_FOUND) self.device_uri = device_uri self.callback = callback self.device_type = DEVICE_TYPE_UNKNOWN if self.device_uri is None: raise Error(ERROR_DEVICE_NOT_FOUND) self.device_uri is None if self.device_uri.startswith('hp:'): self.device_type = DEVICE_TYPE_PRINTER elif self.device_uri.startswith('hpaio:'): self.device_type = DEVICE_TYPE_SCANNER elif self.device_uri.startswith('hpfax:'): self.device_type = DEVICE_TYPE_FAX try: (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.zc, self.port) = parseDeviceURI(self.device_uri) except Error: self.io_state = IO_STATE_NON_HP raise Error(ERROR_INVALID_DEVICE_URI) log.debug('URI: backend=%s, is_hp=%s, bus=%s, model=%s, serial=%s, dev=%s, host=%s, port=%d' % (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port)) self.model_ui = models.normalizeModelUIName(self.model) self.model = models.normalizeModelName(self.model) log.debug('Model/UI model: %s/%s' % (self.model, self.model_ui)) self.mq = { } self.dq = { } self.icon = 'default_printer' self.cups_printers = [] self.channels = { } self.device_id = -1 self.r_values = None self.deviceID = '' self.panel_check = True self.io_state = IO_STATE_HP_READY self.is_local = isLocal(self.bus) self.hist = [] self.supported = False self.queryModel() if not self.supported: log.error('Unsupported model: %s' % self.model) self.error_code = STATUS_DEVICE_UNSUPPORTED self.sendEvent(self.error_code) else: self.supported = True self.mq.update({ 'model': self.model, 'model-ui': self.model_ui }) self.error_state = ERROR_STATE_ERROR self.device_state = DEVICE_STATE_NOT_FOUND self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND self.updateCUPSPrinters() if self.mq.get('fax-type', FAX_TYPE_NONE) != FAX_TYPE_NONE: self.dq.update({ 'fax-uri': self.device_uri.replace('hp:/', 'hpfax:/').replace('hpaio:/', 'hpfax:/') }) if self.mq.get('scan-type', SCAN_TYPE_NONE) != SCAN_TYPE_NONE: self.dq.update({ 'scan-uri': self.device_uri.replace('hp:/', 'hpaio:/').replace('hpfax:/', 'hpaio:/') }) self.dq.update({ 'back-end': self.back_end, 'is-hp': self.is_hp, 'serial': self.serial, 'dev-file': self.dev_file, 'host': self.host, 'port': self.port, 'cups-printers': ','.join(self.cups_printers), 'status-code': self.status_code, 'status-desc': '', 'deviceid': '', 'panel': 0, 'panel-line1': '', 'panel-line2': '', 'device-state': self.device_state, 'error-state': self.error_state, 'device-uri': self.device_uri, 'cups-uri': self.device_uri.replace('hpfax:/', 'hp:/').replace('hpaio:/', 'hp:/') }) self.device_vars = { 'URI': self.device_uri, 'DEVICE_URI': self.device_uri, 'SCAN_URI': self.device_uri.replace('hp:', 'hpaio:'), 'SANE_URI': self.device_uri.replace('hp:', 'hpaio:'), 'FAX_URI': self.device_uri.replace('hp:', 'hpfax:'), 'PRINTER': self.first_cups_printer, 'HOME': prop.home_dir } def sendEvent(self, event_code, printer_name = '', job_id = 0, title = ''): if self.dbus_avail and self.service is not None: try: log.debug('Sending event %d to hpssd...' % event_code) self.service.SendEvent(self.device_uri, printer_name, event_code, prop.username, job_id, title) except dbus.exceptions.DBusException: e = None log.debug('dbus call to SendEvent() failed.') except: None<EXCEPTION MATCH>dbus.exceptions.DBusException None<EXCEPTION MATCH>dbus.exceptions.DBusException def quit(self): pass def queryModel(self): if not self.mq: self.mq = queryModelByURI(self.device_uri) self.supported = bool(self.mq) if self.supported: for m in self.mq: self.__dict__[m.replace('-', '_')] = self.mq[m] def queryString(self, string_id): return queryString(string_id) def open(self, open_for_printing = False): if self.supported and self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL): prev_device_state = self.device_state self.io_state = IO_STATE_HP_NOT_AVAIL self.device_state = DEVICE_STATE_NOT_FOUND self.error_state = ERROR_STATE_ERROR self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND self.device_id = -1 self.open_for_printing = open_for_printing if open_for_printing: log.debug('Opening device: %s (for printing)' % self.device_uri) self.io_mode = self.mq.get('io-mode', hpmudext.HPMUD_UNI_MODE) else: log.debug('Opening device: %s (not for printing)' % self.device_uri) self.io_mode = self.mq.get('io-mfp-mode', hpmudext.HPMUD_UNI_MODE) log.debug('I/O mode=%d' % self.io_mode) (result_code, self.device_id) = hpmudext.open_device(self.device_uri, self.io_mode) if result_code != hpmudext.HPMUD_R_OK: self.error_state = ERROR_STATE_ERROR self.error_code = result_code + ERROR_CODE_BASE self.sendEvent(self.error_code) if result_code == hpmudext.HPMUD_R_DEVICE_BUSY: log.error('Device busy: %s' % self.device_uri) else: log.error('Unable to communicate with device (code=%d): %s' % (result_code, self.device_uri)) self.last_event = Event(self.device_uri, '', EVENT_ERROR_DEVICE_NOT_FOUND, prop.username, 0, '', time.time()) raise Error(ERROR_DEVICE_NOT_FOUND) result_code != hpmudext.HPMUD_R_OK log.debug('device-id=%d' % self.device_id) self.io_state = IO_STATE_HP_OPEN self.error_state = ERROR_STATE_CLEAR log.debug('Opened device: %s (backend=%s, is_hp=%s, bus=%s, model=%s, dev=%s, serial=%s, host=%s, port=%d)' % (self.back_end, self.device_uri, self.is_hp, self.bus, self.model, self.dev_file, self.serial, self.host, self.port)) if prev_device_state == DEVICE_STATE_NOT_FOUND: self.device_state = DEVICE_STATE_JUST_FOUND else: self.device_state = DEVICE_STATE_FOUND self.getDeviceID() self.getSerialNumber() return self.device_id self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL) def close(self): if self.io_state == IO_STATE_HP_OPEN: log.debug('Closing device...') if len(self.channels) > 0: for c in self.channels.keys(): self._Device__closeChannel(c) result_code = hpmudext.close_device(self.device_id) log.debug('Result-code = %d' % result_code) self.channels.clear() self.io_state = IO_STATE_HP_READY def __openChannel(self, service_name): try: if self.io_state == IO_STATE_HP_OPEN: if service_name == hpmudext.HPMUD_S_PRINT_CHANNEL and not (self.open_for_printing): self.close() self.open(True) elif service_name != hpmudext.HPMUD_S_PRINT_CHANNEL and self.open_for_printing: self.close() self.open(False) else: self.open(service_name == hpmudext.HPMUD_S_PRINT_CHANNEL) except: log.error('unable to open channel') return -1 service_name = service_name.upper() if service_name not in self.channels: log.debug('Opening %s channel...' % service_name) (result_code, channel_id) = hpmudext.open_channel(self.device_id, service_name) self.channels[service_name] = channel_id log.debug('channel-id=%d' % channel_id) return channel_id return self.channels[service_name] def openChannel(self, service_name): return self._Device__openChannel(service_name) def openPrint(self): return self._Device__openChannel(hpmudext.HPMUD_S_PRINT_CHANNEL) def openFax(self): return self._Device__openChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL) def openPCard(self): return self._Device__openChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL) def openEWS(self): return self._Device__openChannel(hpmudext.HPMUD_S_EWS_CHANNEL) def closePrint(self): return self._Device__closeChannel(hpmudext.HPMUD_S_PRINT_CHANNEL) def closePCard(self): return self._Device__closeChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL) def closeFax(self): return self._Device__closeChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL) def openPML(self): return self._Device__openChannel(hpmudext.HPMUD_S_PML_CHANNEL) def openWifiConfig(self): return self._Device__openChannel(hpmudext.HPMUD_S_WIFI_CHANNEL) def closePML(self): return self._Device__closeChannel(hpmudext.HPMUD_S_PML_CHANNEL) def closeEWS(self): return self._Device__closeChannel(hpmudext.HPMUD_S_EWS_CHANNEL) def openCfgUpload(self): return self._Device__openChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL) def closeCfgUpload(self): return self._Device__closeChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL) def openCfgDownload(self): return self._Device__openChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL) def closeCfgDownload(self): return self._Device__closeChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL) def openSoapFax(self): return self._Device__openChannel(hpmudext.HPMUD_S_SOAP_FAX) def closeSoapFax(self): return self._Device__closeChannel(hpmudext.HPMUD_S_SOAP_FAX) def closeWifiConfig(self): return self._Device__closeChannel(hpmudext.HPMUD_S_WIFI_CHANNEL) def __closeChannel(self, service_name): if self.io_state == IO_STATE_HP_OPEN: service_name = service_name.upper() if service_name in self.channels: log.debug('Closing %s channel...' % service_name) result_code = hpmudext.close_channel(self.device_id, self.channels[service_name]) del self.channels[service_name] def closeChannel(self, service_name): return self._Device__closeChannel(service_name) def getDeviceID(self): needs_close = False if self.io_state != IO_STATE_HP_OPEN: try: self.open() except: return -1 needs_close = True (result_code, data) = hpmudext.get_device_id(self.device_id) if result_code != hpmudext.HPMUD_R_OK: self.raw_deviceID = '' self.deviceID = { } else: self.raw_deviceID = data self.deviceID = parseDeviceID(data) if needs_close: self.close() return self.deviceID def getSerialNumber(self): if self.serial: return None try: self.serial = self.deviceID['SN'] except KeyError: self.serial self.serial except: self.serial if self.serial: return None if self.serial is None: self.serial = '' def getThreeBitStatus(self): pass def getStatusFromDeviceID(self): self.getDeviceID() return status.parseStatus(parseDeviceID(self.raw_deviceID)) def __parseRValues(self, r_value): r_value_str = str(r_value) r_value_str = ''.join([ '0' * (9 - len(r_value_str)), r_value_str]) rg = r_value_str[:3] rr = r_value_str[3:] r_value = int(rr) self.r_values = (r_value, r_value_str, rg, rr) return (r_value, r_value_str, rg, rr) def getRValues(self, r_type, status_type, dynamic_counters): (r_value, r_value_str, rg, rr) = (0, '000000000', '000', '000000') if r_type > 0 and dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE: if self.r_values is None: if self.dbus_avail: try: r_value = int(self.service.GetCachedIntValue(self.device_uri, 'r_value')) except dbus.exceptions.DBusException: e = None log.debug('dbus call to GetCachedIntValue() failed.') r_value = -1 except: None<EXCEPTION MATCH>dbus.exceptions.DBusException None<EXCEPTION MATCH>dbus.exceptions.DBusException if r_value != -1: log.debug('r_value=%d' % r_value) (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value) return (r_value, r_value_str, rg, rr) if self.r_values is None: if status_type == STATUS_TYPE_S and self.is_local and dynamic_counters != STATUS_DYNAMIC_COUNTERS_PML_SNMP: try: r_value = self.getDynamicCounter(140) if r_value is not None: log.debug('r_value=%d' % r_value) (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value) if self.dbus_avail: try: self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value) except dbus.exceptions.DBusException: e = None log.debug('dbus call to SetCachedIntValue() failed.') except: None<EXCEPTION MATCH>dbus.exceptions.DBusException None<EXCEPTION MATCH>dbus.exceptions.DBusException else: log.error('Error attempting to read r-value (2).') r_value = 0 except Error: log.error('Error attempting to read r-value (1).') r_value = 0 finally: self.closePrint() elif status_type == STATUS_TYPE_S and dynamic_counters == STATUS_DYNAMIC_COUNTERS_PCL or not (self.is_local) or dynamic_counters == STATUS_DYNAMIC_COUNTERS_PML_SNMP: try: (result_code, r_value) = self.getPML(pml.OID_R_SETTING) if r_value is not None: log.debug('r_value=%d' % r_value) (r_value, r_value_str, rg, rr) = self._Device__parseRValues(r_value) if self.dbus_avail: try: self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value) except dbus.exceptions.DBusException: e = None log.debug('dbus call to SetCachedIntValue() failed.') except: None<EXCEPTION MATCH>dbus.exceptions.DBusException None<EXCEPTION MATCH>dbus.exceptions.DBusException else: r_value = 0 finally: self.closePML() else: (r_value, r_value_str, rg, rr) = self.r_values return (r_value, r_value_str, rg, rr) def __queryFax(self, quick = False, reread_cups_printers = False): io_mode = self.mq.get('io-mode', IO_MODE_UNI) self.status_code = STATUS_PRINTER_IDLE if io_mode != IO_MODE_UNI: if self.device_state != DEVICE_STATE_NOT_FOUND: if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK): try: self.getDeviceID() except Error: e = None log.error('Error getting device ID.') self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR, prop.username, 0, '', time.time()) raise Error(ERROR_DEVICE_IO_ERROR) except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error status_desc = self.queryString(self.status_code) self.dq.update({ 'serial': self.serial, 'cups-printers': ','.join(self.cups_printers), 'status-code': self.status_code, 'status-desc': status_desc, 'deviceid': self.raw_deviceID, 'panel': 0, 'panel-line1': '', 'panel-line2': '', 'device-state': self.device_state, 'error-state': self.error_state }) log.debug('Fax activity check...') (tx_active, rx_active) = status.getFaxStatus(self) if tx_active: self.status_code = STATUS_FAX_TX_ACTIVE elif rx_active: self.status_code = STATUS_FAX_RX_ACTIVE self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.status_code, ERROR_STATE_CLEAR) self.error_code = self.status_code self.sendEvent(self.error_code) try: self.dq.update({ 'status-desc': self.queryString(self.status_code), 'error-state': self.error_state }) except (KeyError, Error): self.dq.update({ 'status-desc': '', 'error-state': ERROR_STATE_CLEAR }) if self.panel_check: self.panel_check = bool(self.mq.get('panel-check-type', 0)) status_type = self.mq.get('status-type', STATUS_TYPE_NONE) if self.panel_check and status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and io_mode != IO_MODE_UNI: log.debug('Panel check...') try: (self.panel_check, line1, line2) = status.PanelCheck(self) finally: self.closePML() self.dq.update({ 'panel': int(self.panel_check), 'panel-line1': line1, 'panel-line2': line2 }) if not quick and reread_cups_printers: self.updateCUPSPrinters() for d in self.dq: self.__dict__[d.replace('-', '_')] = self.dq[d] self.last_event = Event(self.device_uri, '', self.status_code, prop.username, 0, '', time.time()) log.debug(self.dq) def updateCUPSPrinters(self): self.cups_printers = [] log.debug('Re-reading CUPS printer queue information.') printers = cups.getPrinters() for p in printers: if self.device_uri == p.device_uri: self.cups_printers.append(p.name) self.state = p.state if self.io_state == IO_STATE_NON_HP: self.model = p.makemodel.split(',')[0] self.io_state == IO_STATE_NON_HP self.dq.update({ 'cups-printers': ','.join(self.cups_printers) }) try: self.first_cups_printer = self.cups_printers[0] except IndexError: self.first_cups_printer = '' def queryDevice(self, quick = False, reread_cups_printers = False): if not self.supported: self.dq = { } self.last_event = Event(self.device_uri, '', STATUS_DEVICE_UNSUPPORTED, prop.username, 0, '', time.time()) return None if self.device_type == DEVICE_TYPE_FAX: return self._Device__queryFax(quick, reread_cups_printers) r_type = self.mq.get('r-type', 0) tech_type = self.mq.get('tech-type', TECH_TYPE_NONE) status_type = self.mq.get('status-type', STATUS_TYPE_NONE) battery_check = self.mq.get('status-battery-check', STATUS_BATTERY_CHECK_NONE) dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE) io_mode = self.mq.get('io-mode', IO_MODE_UNI) io_mfp_mode = self.mq.get('io-mfp-mode', IO_MODE_UNI) status_code = STATUS_UNKNOWN agents = [] if self.device_state != DEVICE_STATE_NOT_FOUND: if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK): try: self.getDeviceID() except Error: self.device_type == DEVICE_TYPE_FAX e = self.device_type == DEVICE_TYPE_FAX self.supported log.error('Error getting device ID.') self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR, prop.username, 0, '', time.time()) raise Error(ERROR_DEVICE_IO_ERROR) except: self.device_type == DEVICE_TYPE_FAX<EXCEPTION MATCH>Error self.device_type == DEVICE_TYPE_FAX status_desc = self.queryString(self.status_code) self.dq.update({ 'serial': self.serial, 'cups-printers': ','.join(self.cups_printers), 'status-code': self.status_code, 'status-desc': status_desc, 'deviceid': self.raw_deviceID, 'panel': 0, 'panel-line1': '', 'panel-line2': '', 'device-state': self.device_state, 'error-state': self.error_state }) status_block = { } if status_type == STATUS_TYPE_NONE: log.warn('No status available for device.') status_block = { 'status-code': STATUS_UNKNOWN } elif status_type in (STATUS_TYPE_VSTATUS, STATUS_TYPE_S): log.debug('Type 1/2 (S: or VSTATUS:) status') status_block = status.parseStatus(self.deviceID) elif status_type in (STATUS_TYPE_LJ, STATUS_TYPE_PML_AND_PJL): log.debug('Type 3/9 LaserJet PML(+PJL) status') status_block = status.StatusType3(self, self.deviceID) elif status_type == STATUS_TYPE_LJ_XML: log.debug('Type 6: LJ XML') status_block = status.StatusType6(self) elif status_type == STATUS_TYPE_PJL: log.debug('Type 8: LJ PJL') status_block = status.StatusType8(self) else: log.error('Unimplemented status type: %d' % status_type) if battery_check and io_mode != IO_MODE_UNI: log.debug('Battery check...') status.BatteryCheck(self, status_block, battery_check) if status_block: log.debug(status_block) self.dq.update(status_block) try: status_block['agents'] except KeyError: pass agents = status_block['agents'] del self.dq['agents'] status_code = self.dq.get('status-code', STATUS_UNKNOWN) self.error_state = STATUS_TO_ERROR_STATE_MAP.get(status_code, ERROR_STATE_CLEAR) self.error_code = status_code self.sendEvent(self.error_code) try: self.dq.update({ 'status-desc': self.queryString(status_code), 'error-state': self.error_state }) except (KeyError, Error): self.dq.update({ 'status-desc': '', 'error-state': ERROR_STATE_CLEAR }) r_value = 0 if not quick and status_type != STATUS_TYPE_NONE: if self.panel_check: self.panel_check = bool(self.mq.get('panel-check-type', 0)) if self.panel_check and status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and io_mode != IO_MODE_UNI: log.debug('Panel check...') try: (self.panel_check, line1, line2) = status.PanelCheck(self) finally: self.closePML() self.dq.update({ 'panel': int(self.panel_check), 'panel-line1': line1, 'panel-line2': line2 }) if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE and io_mode != IO_MODE_UNI: (r_value, r_value_str, rg, rr) = self.getRValues(r_type, status_type, dynamic_counters) else: (r_value, r_value_str, rg, rr) = (0, '000000000', '000', '000000') self.dq.update({ 'r': r_value, 'rs': r_value_str, 'rg': rg, 'rr': rr }) if not quick and reread_cups_printers: self.updateCUPSPrinters() if not quick: if r_value > 0 and self.mq.get('r%d-agent1-kind' % r_value, 0) == 0: r_value = 0 self.dq.update({ 'r': r_value, 'rs': r_value_str, 'rg': rg, 'rr': rr }) (a, aa) = (1, 1) while True: mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), -1) if mq_agent_kind == -1: break mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0) mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '') found = False log.debug('Looking for kind=%d, type=%d...' % (mq_agent_kind, mq_agent_type)) for agent in agents: agent_kind = agent['kind'] agent_type = agent['type'] if agent_kind == mq_agent_kind and agent_type == mq_agent_type: found = True break continue if found: log.debug('found: r%d-kind%d-type%d' % (r_value, agent_kind, agent_type)) agent_health = agent.get('health', AGENT_HEALTH_OK) agent_level = agent.get('level', 100) agent_level_trigger = agent.get('level-trigger', AGENT_LEVEL_TRIGGER_SUFFICIENT_0) log.debug('health=%d, level=%d, level_trigger=%d, status_code=%d' % (agent_health, agent_level, agent_level_trigger, status_code)) query = 'agent_%s_%s' % (AGENT_types.get(agent_type, 'unknown'), AGENT_kinds.get(agent_kind, 'unknown')) agent_desc = self.queryString(query) query = 'agent_health_ok' if status_code == STATUS_PRINTER_IDLE or status_code == STATUS_PRINTER_OUT_OF_INK: if (agent_health == AGENT_HEALTH_OK or agent_health == AGENT_HEALTH_FAIR_MODERATE or agent_kind == AGENT_KIND_HEAD) and agent_level_trigger >= AGENT_LEVEL_TRIGGER_MAY_BE_LOW: query = 'agent_level_%s' % AGENT_levels.get(agent_level_trigger, 'unknown') if tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK): code = agent_type + STATUS_PRINTER_LOW_INK_BASE else: code = agent_type + STATUS_PRINTER_LOW_TONER_BASE self.dq['status-code'] = code self.dq['status-desc'] = self.queryString(code) self.dq['error-state'] = STATUS_TO_ERROR_STATE_MAP.get(code, ERROR_STATE_LOW_SUPPLIES) self.error_code = code self.sendEvent(self.error_code) if agent_level_trigger in (AGENT_LEVEL_TRIGGER_PROBABLY_OUT, AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT): query = 'agent_level_out' else: query = 'agent_level_low' agent_health_desc = self.queryString(query) self.dq.update({ 'agent%d-kind' % aa: agent_kind, 'agent%d-type' % aa: agent_type, 'agent%d-known' % aa: agent.get('known', False), 'agent%d-sku' % aa: mq_agent_sku, 'agent%d-level' % aa: agent_level, 'agent%d-level-trigger' % aa: agent_level_trigger, 'agent%d-ack' % aa: agent.get('ack', False), 'agent%d-hp-ink' % aa: agent.get('hp-ink', False), 'agent%d-health' % aa: agent_health, 'agent%d-dvc' % aa: agent.get('dvc', 0), 'agent%d-virgin' % aa: agent.get('virgin', False), 'agent%d-desc' % aa: agent_desc, 'agent%d-id' % aa: agent.get('id', 0), 'agent%d-health-desc' % aa: agent_health_desc }) else: query = 'agent_health_%s' % AGENT_healths.get(agent_health, AGENT_HEALTH_OK) agent_health_desc = self.queryString(query) self.dq.update({ 'agent%d-kind' % aa: agent_kind, 'agent%d-type' % aa: agent_type, 'agent%d-known' % aa: False, 'agent%d-sku' % aa: mq_agent_sku, 'agent%d-level' % aa: agent_level, 'agent%d-level-trigger' % aa: agent_level_trigger, 'agent%d-ack' % aa: False, 'agent%d-hp-ink' % aa: False, 'agent%d-health' % aa: agent_health, 'agent%d-dvc' % aa: 0, 'agent%d-virgin' % aa: False, 'agent%d-desc' % aa: agent_desc, 'agent%d-id' % aa: 0, 'agent%d-health-desc' % aa: agent_health_desc }) aa += 1 else: log.debug('Not found: %d' % a) a += 1 else: r_value = 0 if r_type > 0 and self.r_values is not None: r_value = self.r_values[0] if r_value > 0 and self.mq.get('r%d-agent1-kind', 0) == 0: r_value = 0 a = 1 while True: mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), 0) if mq_agent_kind == 0: break mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0) mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '') query = 'agent_%s_%s' % (AGENT_types.get(mq_agent_type, 'unknown'), AGENT_kinds.get(mq_agent_kind, 'unknown')) agent_desc = self.queryString(query) self.dq.update({ 'agent%d-kind' % a: mq_agent_kind, 'agent%d-type' % a: mq_agent_type, 'agent%d-known' % a: False, 'agent%d-sku' % a: mq_agent_sku, 'agent%d-level' % a: 0, 'agent%d-level-trigger' % a: AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT, 'agent%d-ack' % a: False, 'agent%d-hp-ink' % a: False, 'agent%d-health' % a: AGENT_HEALTH_MISINSTALLED, 'agent%d-dvc' % a: 0, 'agent%d-virgin' % a: False, 'agent%d-health-desc' % a: self.queryString('agent_health_unknown'), 'agent%d-desc' % a: agent_desc, 'agent%d-id' % a: 0 }) a += 1 for d in self.dq: self.__dict__[d.replace('-', '_')] = self.dq[d] self.last_event = Event(self.device_uri, '', status_code, prop.username, 0, '', time.time()) log.debug(self.dq) def isBusyOrInErrorState(self): try: self.queryDevice(quick = True) except Error: return True return self.error_state in (ERROR_STATE_ERROR, ERROR_STATE_BUSY) def isIdleAndNoError(self): try: self.queryDevice(quick = True) except Error: return False return self.error_state not in (ERROR_STATE_ERROR, ERROR_STATE_BUSY) def getPML(self, oid, desired_int_size = pml.INT_SIZE_INT): channel_id = self.openPML() (result_code, data, typ, pml_result_code) = hpmudext.get_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1]) if pml_result_code > pml.ERROR_MAX_OK: log.debug('PML/SNMP GET %s failed (result code = 0x%x)' % (oid[0], pml_result_code)) return (pml_result_code, None) converted_data = pml.ConvertFromPMLDataFormat(data, oid[1], desired_int_size) if log.is_debug(): if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY): log.debug('PML/SNMP GET %s (result code = 0x%x) returned:' % (oid[0], pml_result_code)) log.log_data(data) else: log.debug('PML/SNMP GET %s (result code = 0x%x) returned: %s' % (oid[0], pml_result_code, repr(converted_data))) return (pml_result_code, converted_data) def setPML(self, oid, value): channel_id = self.openPML() value = pml.ConvertToPMLDataFormat(value, oid[1]) (result_code, pml_result_code) = hpmudext.set_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1], value) if log.is_debug(): if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY): log.debug('PML/SNMP SET %s (result code = 0x%x) to:' % (oid[0], pml_result_code)) log.log_data(value) else: log.debug('PML/SNMP SET %s (result code = 0x%x) to: %s' % (oid[0], pml_result_code, repr(value))) return pml_result_code def getDynamicCounter(self, counter, convert_to_int = True): dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE) log.debug('Dynamic counters: %d' % dynamic_counters) if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE: if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4: self.printData(ldl.buildResetPacket(), direct = True) self.printData(ldl.buildDynamicCountersPacket(counter), direct = True) else: self.printData(pcl.buildDynamicCounter(counter), direct = True) (value, tries, times_seen, sleepy_time, max_tries) = (0, 0, 0, 0.1, 5) time.sleep(0.1) while True: if self.callback: self.callback() sleepy_time += 0.1 tries += 1 time.sleep(sleepy_time) self.getDeviceID() if 'CTR' in self.deviceID and pat_dynamic_ctr.search(self.raw_deviceID) is not None: (dev_counter, value) = parseDynamicCounter(self.deviceID['CTR'], convert_to_int) if counter == dev_counter: self.printData(pcl.buildDynamicCounter(0), direct = True) if not convert_to_int: value = '#' + value return value if tries > max_tries: if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4: self.printData(ldl.buildResetPacket()) self.printData(ldl.buildDynamicCountersPacket(counter), direct = True) else: self.printData(pcl.buildDynamicCounter(0), direct = True) return None if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4: self.printData(ldl.buildResetPacket()) self.printData(ldl.buildDynamicCountersPacket(counter), direct = True) continue tries > max_tries self.printData(pcl.buildDynamicCounter(counter), direct = True) else: raise Error(ERROR_DEVICE_DOES_NOT_SUPPORT_OPERATION) return dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE def readPrint(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): return self._Device__readChannel(self.openPrint, bytes_to_read, stream, timeout, allow_short_read) def readPCard(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): return self._Device__readChannel(self.openPCard, bytes_to_read, stream, timeout, allow_short_read) def readFax(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): return self._Device__readChannel(self.openFax, bytes_to_read, stream, timeout, allow_short_read) def readCfgUpload(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): return self._Device__readChannel(self.openCfgUpload, bytes_to_read, stream, timeout, allow_short_read) def readEWS(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = True): return self._Device__readChannel(self.openEWS, bytes_to_read, stream, timeout, allow_short_read) def readSoapFax(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = True): return self._Device__readChannel(self.openSoapFax, bytes_to_read, stream, timeout, allow_short_read) def readWifiConfig(self, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = True): return self._Device__readChannel(self.openWifiConfig, bytes_to_read, stream, timeout, allow_short_read) def __readChannel(self, opener, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): channel_id = opener() log.debug('Reading channel %d (device-id=%d, bytes_to_read=%d, allow_short=%s, timeout=%d)...' % (channel_id, self.device_id, bytes_to_read, allow_short_read, timeout)) num_bytes = 0 if stream is None: buffer = '' while True: (result_code, data) = hpmudext.read_channel(self.device_id, channel_id, bytes_to_read, timeout) log.debug('Result code=%d' % result_code) l = len(data) if result_code == hpmudext.HPMUD_R_IO_TIMEOUT: log.debug('I/O timeout') break if result_code != hpmudext.HPMUD_R_OK: log.error('Channel read error') raise Error(ERROR_DEVICE_IO_ERROR) result_code != hpmudext.HPMUD_R_OK if not l: log.debug('End of data') break if stream is None: buffer = ''.join([ buffer, data]) else: stream.write(data) num_bytes += l if self.callback is not None: self.callback() if num_bytes == bytes_to_read: log.debug('Full read complete.') break if allow_short_read and num_bytes < bytes_to_read: log.debug('Allowed short read of %d of %d bytes complete.' % (num_bytes, bytes_to_read)) break continue if stream is None: log.debug('Returned %d total bytes in buffer.' % num_bytes) return buffer log.debug('Saved %d total bytes to stream.' % num_bytes) return num_bytes def writePrint(self, data): return self._Device__writeChannel(self.openPrint, data) def writePCard(self, data): return self._Device__writeChannel(self.openPCard, data) def writeFax(self, data): return self._Device__writeChannel(self.openFax, data) def writeEWS(self, data): return self._Device__writeChannel(self.openEWS, data) def writeCfgDownload(self, data): return self._Device__writeChannel(self.openCfgDownload, data) def writeSoapFax(self, data): return self._Device__writeChannel(self.openSoapFax, data) def writeWifiConfig(self, data): return self._Device__writeChannel(self.openWifiConfig, data) def __writeChannel(self, opener, data): channel_id = opener() buffer = data bytes_out = 0 total_bytes_to_write = len(data) log.debug('Writing %d bytes to channel %d (device-id=%d)...' % (total_bytes_to_write, channel_id, self.device_id)) while len(buffer) > 0: (result_code, bytes_written) = hpmudext.write_channel(self.device_id, channel_id, buffer[:prop.max_message_len]) log.debug('Result code=%d' % result_code) if result_code != hpmudext.HPMUD_R_OK: log.error('Channel write error') raise Error(ERROR_DEVICE_IO_ERROR) result_code != hpmudext.HPMUD_R_OK buffer = buffer[prop.max_message_len:] bytes_out += bytes_written if self.callback is not None: self.callback() continue if total_bytes_to_write != bytes_out: raise Error(ERROR_DEVICE_IO_ERROR) total_bytes_to_write != bytes_out return bytes_out def writeEmbeddedPML(self, oid, value, style = 1, direct = True): if style == 1: func = pcl.buildEmbeddedPML2 else: func = pcl.buildEmbeddedPML data = func(pcl.buildPCLCmd('&', 'b', 'W', pml.buildEmbeddedPMLSetPacket(oid[0], value, oid[1]))) log.log_data(data) self.printData(data, direct = direct, raw = True) def printGzipFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False): return self.printFile(file_name, printer_name, direct, raw, remove) def printParsedGzipPostscript(self, print_file, printer_name = None): try: os.stat(print_file) except OSError: log.error('File not found: %s' % print_file) return None (temp_file_fd, temp_file_name) = utils.make_temp_file() f = gzip.open(print_file, 'r') x = f.readline() while not x.startswith('%PY_BEGIN'): os.write(temp_file_fd, x) x = f.readline() sub_lines = [] x = f.readline() while not x.startswith('%PY_END'): sub_lines.append(x) x = f.readline() SUBS = { 'VERSION': prop.version, 'MODEL': self.model_ui, 'URI': self.device_uri, 'BUS': self.bus, 'SERIAL': self.serial, 'IP': self.host, 'PORT': self.port, 'DEVNODE': self.dev_file } if self.bus == 'net': SUBS['DEVNODE'] = 'n/a' else: SUBS['IP'] = 'n/a' SUBS['PORT'] = 'n/a' for s in sub_lines: os.write(temp_file_fd, s % SUBS) os.write(temp_file_fd, f.read()) f.close() os.close(temp_file_fd) self.printFile(temp_file_name, printer_name, direct = False, raw = False, remove = True) def printFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False): is_gzip = os.path.splitext(file_name)[-1].lower() == '.gz' if printer_name is None: printer_name = self.first_cups_printer if not printer_name: raise Error(ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE) printer_name log.debug("Printing file '%s' to queue '%s' (gzip=%s, direct=%s, raw=%s, remove=%s)" % (file_name, printer_name, is_gzip, direct, raw, remove)) if direct: if is_gzip: self.writePrint(gzip.open(file_name, 'r').read()) else: self.writePrint(file(file_name, 'r').read()) elif not utils.which('lpr'): lp_opt = '' if raw: lp_opt = '-oraw' if is_gzip: c = 'gunzip -c %s | lp -c -d%s %s' % (file_name, printer_name, lp_opt) else: c = 'lp -c -d%s %s %s' % (printer_name, lp_opt, file_name) log.debug(c) exit_code = os.system(c) if exit_code != 0: log.error('Print command failed with exit code %d!' % exit_code) if remove: os.remove(file_name) else: (raw_str, rem_str) = ('', '') if raw: raw_str = '-o raw' if remove: rem_str = '-r' if is_gzip: c = 'gunzip -c %s | lpr %s %s -P%s' % (file_name, raw_str, rem_str, printer_name) else: c = 'lpr -P%s %s %s %s' % (printer_name, raw_str, rem_str, file_name) log.debug(c) exit_code = os.system(c) if exit_code != 0: log.error('Print command failed with exit code %d!' % exit_code) def printTestPage(self, printer_name = None): return self.printParsedGzipPostscript(os.path.join(prop.home_dir, 'data', 'ps', 'testpage.ps.gz'), printer_name) def printData(self, data, printer_name = None, direct = True, raw = True): if direct: self.writePrint(data) else: (temp_file_fd, temp_file_name) = utils.make_temp_file() os.write(temp_file_fd, data) os.close(temp_file_fd) self.printFile(temp_file_name, printer_name, False, raw, remove = True) def cancelJob(self, jobid): cups.cancelJob(jobid) self.error_code = STATUS_PRINTER_CANCELING self.sendEvent(self.error_code) def queryHistory(self): result = [] if self.dbus_avail: try: (device_uri, history) = self.service.GetHistory(self.device_uri) except dbus.exceptions.DBusException: e = None log.error('dbus call to GetHistory() failed.') return [] history.reverse() for h in history: result.append(Event(*tuple(h))) try: self.error_code = result[0].event_code except IndexError: self.error_code = STATUS_UNKNOWN self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.error_code, ERROR_STATE_CLEAR) else: self.error_code = STATUS_UNKNOWN self.error_state = ERROR_STATE_CLEAR self.hist = result return result def getEWSUrl(self, url, stream): try: if self.is_local: url2 = '%s&loc=%s' % (self.device_uri.replace('hpfax:', 'hp:'), url) data = self else: url2 = 'http://%s%s' % (self.host, url) if self.zc: (status, ip) = hpmudext.get_zc_ip_address(self.zc) if status == hpmudext.HPMUD_R_OK: url2 = 'http://%s%s' % (ip, url) data = None log.debug('Opening: %s' % url2) opener = LocalOpener({ }) try: f = opener.open(url2, data) except Error: log.error('Status read failed: %s' % url2) stream.seek(0) stream.truncate() try: stream.write(f.read()) finally: f.close() finally: self.closeEWS() def downloadFirmware(self, usb_bus_id = None, usb_device_id = None): ok = False filename = os.path.join(prop.data_dir, 'firmware', self.model.lower() + '.fw.gz') log.debug(filename) if os.path.exists(filename): log.debug("Downloading firmware file '%s'..." % filename) try: self.openPrint() bytes_written = self.writePrint(gzip.open(filename).read()) log.debug('%s bytes downloaded.' % utils.commafy(bytes_written)) self.closePrint() ok = True log.debug('OK') except Error: e = None log.error('An error occured: %s' % e.msg) except: None<EXCEPTION MATCH>Error None<EXCEPTION MATCH>Error log.error("Firmware file '%s' not found." % filename) return ok class xStringIO(StringIO.StringIO): def makefile(self, x, y): return self class LocalOpener(urllib.URLopener): def open_hp(self, url, dev): log.debug('open_hp(%s)' % url) match_obj = http_pat_url.search(url) if not match_obj.group(1): pass bus = '' if not match_obj.group(2): pass model = '' if not match_obj.group(3): pass serial = '' if not match_obj.group(4): pass device = '' if not match_obj.group(5): pass loc = '' dev.openEWS() dev.writeEWS('GET %s HTTP/1.0\nContent-Length:0\nHost:localhost\nUser-Agent:hplip\n\n' % loc) reply = xStringIO() while dev.readEWS(8192, reply, timeout = 1): pass reply.seek(0) log.log_data(reply.getvalue()) response = httplib.HTTPResponse(reply) response.begin() if response.status != httplib.OK: raise Error(ERROR_DEVICE_STATUS_NOT_AVAILABLE) response.status != httplib.OK return response.fp